from peewee import *
from src.models.BaseModel import BaseModel
from src.util.Model2Dict import m2d
from src.entry.Entrys import Page

""" 角色表 """


class Role(BaseModel):
    rId = BigIntegerField(db_column='r_id', primary_key=True)
    name = CharField(db_column='name')
    key = CharField(db_column='key')
    status = CharField()
    initBy = BigIntegerField(db_column='init_by')
    initTime = DateTimeField(db_column='init_time')
    updateBy = BigIntegerField(db_column='update_by')
    updateTime = DateTimeField(db_column='update_time')
    sys = CharField()
    indexPath = CharField(db_column='index_path')

    # 设置模型对应的数据库表名
    class Meta:
        table_name = 'sys_role'

    # 获取所有的角色
    @staticmethod
    def getAllRole(page: Page = Page(), cdn: dict = None):
        if cdn is None:
            cdn = dict()
        query = Role.select()
        if cdn.get('key'):
            query = query.where(Role.key == cdn.get('key'))
        if cdn.get('status'):
            query = query.where(Role.status == cdn.get('status'))
        if cdn.get('name'):
            query = query.where(Role.name.contains(cdn.get('name')))
        r = query.paginate(page.num, page.size).dicts()
        page.count = query.count()
        page.rows = m2d(r)
        return page.__dict__

    # 获取所有的角色名
    @staticmethod
    def getAllRoleName(page: Page = Page()):
        r = Role.select(Role.rId, Role.name).paginate(page.num, page.size).dicts()
        page.count = Role.select().count()
        page.rows = m2d(r)
        return page.__dict__

    # 获取角色id列表里 的所有角色名
    @staticmethod
    def getRoleNameInIsd(rids: list[int]):
        return m2d(Role.select(Role.rId, Role.name, Role.status, Role.indexPath).where(Role.rId.in_(rids)).dicts())

    @staticmethod
    def updateRole(r_id, k):
        return Role.update(k).where(Role.rId == r_id).execute() > 0

    # 添加新的角色
    @staticmethod
    def addRole(d: dict):
        return Role.insert(d).execute()

    # 删除角色
    @staticmethod
    def delRoleInId(r_ids: list[int]):
        return Role.delete().where(Role.rId.in_(r_ids)).execute() > 0

    # 根据查询 id list 里的 角色
    @staticmethod
    def getRolesInId(ids: list[int]):
        results = Role.select().where(Role.rId.in_(ids)).dicts()
        return m2d(results)

    @staticmethod
    def getCanUseRoleIdsInId(ids: list[int]):
        results = Role.select(Role.rId).where(Role.rId.in_(ids), Role.status == '1').dicts()
        return [item['rId'] for item in m2d(results)]

    # 查询角色使用状态
    @staticmethod
    def getRoleStatus(r_id):
        result = Role.select(Role.status).where(Role.rId == r_id).dicts().execute()
        if len(result) > 0:
            return m2d(result)[0]["status"]
        else:
            return None

    # 判断是否拥有该角色
    @staticmethod
    def hasRole(rid) -> bool:
        return Role.select(Role.rId).where(Role.rId == rid).count() > 0


""" 角色操作权限映射 """


class RoleHandleMapping(BaseModel):
    rId = BigIntegerField(db_column='r_id')
    hId = BigIntegerField(db_column='h_id')

    # 设置模型对应的数据库表名
    class Meta:
        table_name = 'sys_role_handle'

    @staticmethod
    # 检查这些角色里是否拥有接口权限
    def hasRolesHandle(rids: list[int], hid: int) -> bool:
        if RoleHandleMapping.select(RoleHandleMapping.hId) \
                .where(RoleHandleMapping.rId.in_(rids), RoleHandleMapping.hId == hid).count() > 0:
            return True
        return False

    # 删除所有有hid 的映射关系
    @staticmethod
    def delRoleHandleInHid(h_ids: list[int]):
        return RoleHandleMapping.delete().where(RoleHandleMapping.hId.in_(h_ids)).execute()

    # 批量删除所有角色拥有的接口映射关系
    @staticmethod
    def delRoleHandleInRid(rids: list[int]):
        return RoleHandleMapping.delete().where(RoleHandleMapping.rId.in_(rids)).execute()

    # 查询角色所有的操作权限ids
    @staticmethod
    def getRoleHandles(r_id) -> list[int]:
        handles: list[RoleHandleMapping] = RoleHandleMapping.select(RoleHandleMapping.hId).where(
            RoleHandleMapping.rId == r_id).dicts().execute()
        return [item["hId"] for item in m2d(handles)]

    # 为用户添加操作
    @staticmethod
    def addRoleHandle(rid: int, h_ids: list[int]):
        d = list()
        for item in h_ids:
            d.append({"rId": rid, "hId": item})
        if len(d) > 0:
            RoleHandleMapping.insert_many(d).execute()
        return True


""" 角色菜单路由映射 """


class RoleMenuMapping(BaseModel):
    rId = BigIntegerField(db_column='r_id')
    mId = BigIntegerField(db_column='m_id')

    # 设置模型对应的数据库表名
    class Meta:
        table_name = 'sys_role_menu'

    # 查询角色的菜单权限ids
    @staticmethod
    def getRoleMenusIds(r_id) -> list[int]:
        menus: list[RoleMenuMapping] = RoleMenuMapping.select(RoleMenuMapping.mId).where(
            RoleMenuMapping.rId == r_id).dicts().execute()
        return [item["mId"] for item in m2d(menus)]

    # 删除所有有rid 的映射关系
    @staticmethod
    def delRoleMenuInRid(rids: list[int]):
        count = RoleMenuMapping.delete().where(RoleMenuMapping.rId.in_(rids)).execute()
        if count > 0:
            return True
        return False

    # 为用户添加菜单
    @staticmethod
    def addRoleMenu(rid: int, m_ids: list[int]):
        d = list()
        for item in m_ids:
            d.append({"rId": rid, "mId": item})
        if len(d) > 0:
            RoleMenuMapping.insert_many(d).execute()
        return True

    # 查询是否拥有某菜单权限
    @staticmethod
    def hasRoleMenu(rid: int, mid: int) -> bool:
        if RoleMenuMapping.select(RoleMenuMapping.mId).where(RoleMenuMapping.rId == rid,
                                                             RoleMenuMapping.mId == mid).count() > 0:
            return True
        return False

    # 批量删除所有有角色菜单映射关系
    @staticmethod
    def delRoleMenuInMid(m_ids: list[int]):
        return RoleMenuMapping.delete().where(RoleMenuMapping.mId.in_(m_ids)).execute()


""" 角色菜单按钮映射表"""


class RoleButtonMapping(BaseModel):
    rId = BigIntegerField(db_column='r_id')
    tag = CharField(db_column='tag')

    # 设置模型对应的数据库表名
    class Meta:
        table_name = 'sys_role_button'

    # 添加角色用户菜单按钮
    @staticmethod
    def addRoleButton(rid, tags: list[str]):
        d = list()
        for item in tags:
            d.append({"rId": rid, "tag": item})
        if len(d) > 0:
            RoleButtonMapping.insert_many(d).execute()
        return True

    # 删除角色菜单按钮 根据 权限Tag
    @staticmethod
    def delRoleButtonInTag(tag: list[str]):
        return RoleButtonMapping.delete().where(RoleButtonMapping.tag.in_(tag)).execute()

    # 清空角色用户菜单按钮(根据角色id)
    @staticmethod
    def delRoleButtonInRid(rid: list[int]):
        return RoleButtonMapping.delete().where(RoleButtonMapping.rId.in_(rid)).execute()

    # 根据角色获取角色拥有的所有按钮id
    @staticmethod
    def getRoleButtonAll(rid: int) -> list[str]:
        r = RoleButtonMapping.select(RoleButtonMapping.tag).where(RoleButtonMapping.rId == rid).dicts()
        return [item['tag'] for item in m2d(r)]
